
package com.fm.service.file.smo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.fm.MDA;
import com.fm.service.dto.Attachment;
import com.fm.util.DateUtil;

import net.sf.json.JSONArray;

@Service
public class FileOperSMOImpl implements IFileOperSMO {

	private static final Logger logger = LogManager.getLogger(FileOperSMOImpl.class);
	
	@Autowired
	private Environment env;//执行环境

	@Override
	public Map<String, Object> batchUploadFiles(MultipartHttpServletRequest request) {
		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("resultCode", "0");
		resultMap.put("resultMsg", "成功");

		try {
			// 获取所有
			Iterator<String> fileNames = request.getFileNames();

			List<MultipartFile> files = new ArrayList<>();
			while (fileNames.hasNext()) {
				// 每个组件中的上传状态（0，全部成功，1有失败）
				String fileName = (String) fileNames.next();
				// 获取所有的文件
				files.addAll(((MultipartHttpServletRequest) request).getFiles(fileName));
			}

			//1.0 文件后缀。大小等限制校验
			Map<String,Object> checkMap = checkFiles(files);
			if(!"0".equals(checkMap.get("resultCode").toString())){
				return checkMap;
			}
			
			// 所有返回结果
			List<Attachment> attachments = new ArrayList<>();
			// 多组件，多文件
			FileOutputStream fos = null;
			FileInputStream fis = null;
			for (MultipartFile file : files) {
				// 返回的单个文件
				Attachment attachment = new Attachment();

				if (!file.isEmpty()) {
					File outFile = null;
					// 文件全称
					String uploadFilePath = null;
					// 截取上传文件的文件名
					String uploadFileName = null;
					// 截取上传文件的后缀
					String uploadFileSuffix = null;
					// 上传装填
					String status = "0";
					// 上传信息
					String remark = "upload success.";
					try {

						uploadFilePath = file.getOriginalFilename();
						logger.debug("==uploadFlePath : " + uploadFilePath);
						// 截取上传文件的文件名
						uploadFileName = uploadFilePath.substring(uploadFilePath.lastIndexOf('\\') + 1,
								uploadFilePath.indexOf('.'));
						logger.debug("==multiReq.getFile() : " + uploadFileName);
						// 截取上传文件的后缀
						uploadFileSuffix = uploadFilePath.substring(uploadFilePath.lastIndexOf('.') + 1,
								uploadFilePath.length());
						logger.debug("==uploadFileSuffix : " + uploadFileSuffix);
						// TODO 文件名称转换，可直接UTF-8命名
						outFile = getOutPutFile(uploadFileName,uploadFileSuffix);
						fis = (FileInputStream) file.getInputStream();
						fos = new FileOutputStream(outFile);
						byte[] temp = new byte[2048];
						int ri = fis.read(temp);
						while (ri != -1) {
							fos.write(temp, 0, temp.length);
							fos.flush();
							ri = fis.read(temp);
						}

					} catch (Exception e) {
						logger.error("== file read error. " + file.getOriginalFilename() + " : " + e.getMessage());
						status = "1";
						remark = e.getMessage();
					} finally {
						try {
							if (fos != null) {
								fos.close();
							}
						} catch (IOException e) {
							logger.error(e.getMessage());
						}
					}

					// 返回的单个attachment
					// 该文件信息
					attachment.setAttachFullName(uploadFilePath);
					attachment.setAttachName(uploadFileName);
					attachment.setAttachSuffix(uploadFileSuffix);
					attachment.setAttachAbsolutePath(outFile.getAbsolutePath());
					//可访问路劲
					if(MDA.UPLOAD_IMG_FOLDER.equals(MDA.FILE_SUFFIX.get(uploadFileSuffix.toLowerCase()))){
						//图片路劲
						StringBuffer urlPath = new StringBuffer();
						//添加相对路劲
						urlPath.append(MDA.FILE_SUFFIX.get(uploadFileSuffix.toLowerCase()));
						//添加文件名
						urlPath.append("/"+outFile.getName());
						//添加后缀
						attachment.setAttachPath(urlPath.toString());
					}else{
						attachment.setAttachPath(outFile.getName());
					}
					attachment.setAttachSize(file.getSize());
					attachment.setUploadDt(DateUtil.getNow(DateUtil.DATE_FORMATE_STRING_A));
					attachment.setUploadStatus(status);
					attachment.setRemark(remark);
				} else {
					logger.debug("上传文件为空");
					attachment.setAttachFullName(file.getOriginalFilename());
					attachment.setAttachSize(file.getSize());
					attachment.setUploadStatus("1");
					attachment.setRemark("file is empty。");
				}

				// 添加组件下附件列表
				attachments.add(attachment);
			} // end of for

			resultMap.put("result", JSONArray.fromObject(attachments));

		} catch (Exception e) {
			logger.debug("文件上传失败.."+e.getMessage());
			resultMap.put("resultCode", "-1");
			resultMap.put("resultMsg", e.getMessage());
		}
		return resultMap;
	}
	
	private File getOutPutFile(String uploadFileName,String uploadFileSuffix){
		StringBuffer filePath = new StringBuffer();
		//添加根路劲 修改根路劲
		//filePath.append(MDA.SYSTEM_REAL_PATH);
		filePath.append(env.getProperty(MDA.KEY_ABSOLUTE_PATH.get(MDA.FILE_SUFFIX.get(uploadFileSuffix.toLowerCase())).toString()));
		//文件路劲
		filePath.append("//"+MDA.FILE_SUFFIX.get(uploadFileSuffix.toLowerCase()));
		//文件夹不存在则创建
		File file = new File(filePath.toString());
		if(!file.exists()){
			file.mkdirs();
		};
		//UUID 文件名
		filePath.append("//"+UUID.randomUUID().toString());
		//文件后缀
		filePath.append(".");
		filePath.append(uploadFileSuffix);
		logger.debug("创建文件名称："+filePath);	
		return new File(filePath.toString());
	}

	private Map<String, Object> checkFiles(List<MultipartFile> files) {
		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("resultCode", "0");
		resultMap.put("resultMsg", "文件校验成功。");
		try {
			List<Attachment> attachments = new ArrayList<>();
			for(MultipartFile file : files){
				Attachment attachment = new Attachment();
				// 文件后缀
				String uploadFilePath = file.getOriginalFilename();
				// 截取上传文件的后缀
				String uploadFileSuffix = uploadFilePath.substring(uploadFilePath.lastIndexOf('.') + 1,uploadFilePath.length());
				
				//文件后缀
				if(!MDA.FILE_SUFFIX.keySet().contains(uploadFileSuffix.toLowerCase())){
					attachment.setAttachFullName(file.getOriginalFilename());
					attachment.setUploadStatus("1");
					attachment.setRemark("不支持的文件后缀.");
					attachments.add(attachment);				
					logger.debug("不支持的文件后缀："+ uploadFileSuffix + ",文件名称：" + uploadFilePath);	
					continue;
				}
				//文件大小
				if(file.getSize() > (MDA.MAX_FILE_SIZE*1024*1024)){
					attachment.setAttachFullName(file.getOriginalFilename());
					attachment.setUploadStatus("1");
					attachment.setRemark("文件过大（超过"+MDA.MAX_FILE_SIZE+"M）.");
					attachments.add(attachment);
					logger.debug("上传文件过大："+ file.getSize()/1024 + ",文件名称：" + uploadFilePath);	
					continue;
				}
			}
			
			if(attachments.size() > 0){
				resultMap.put("resultCode", "-1");
				resultMap.put("resultMsg", "文件校验失败.");
				resultMap.put("result", JSONArray.fromObject(attachments));
			}
		} catch (Exception e) {
			logger.error( "文件校验失败."+ e.getMessage());
			resultMap.put("resultCode", "-1");
			resultMap.put("resultMsg", "文件校验失败."+ e.getMessage());
		}
		return resultMap;
	}

}
